<?php
declare (strict_types = 1);

namespace app\admin\model\system;

use bbweb\traits\ModelTrait;
use bbweb\basic\BaseModel;

/**
 * @mixin \think\Model
 */
class SystemRole extends BaseModel
{
    /**
     * 数据表主键
     * @var string
     */
    protected $pk = 'id';

    /**
     * 模型名称
     * @var string
     */
    protected $name = 'system_role';

    use ModelTrait;

    // 设置字段信息
    protected $schema = [
        'id'        => 'int',
        'pid'       => 'int',
        'parent'    => 'int',
        'sys'       => 'tinyint',
        'type'      => 'tinyint',
        'role_name' => 'varchar',
        'roles'     => 'text',
        'status'    => 'tinyint',
        'path'      => 'varchar',
        'child'     => 'tinyint',
        'update_at' => 'int'
    ];

    public static function getRolesAttr($value)
    {
        return explode(',',$value);
    }

    public static function roleAll()
    {
        $roleAll = self::order('sys DESC,id ASC')->select();
        return self::tidyRoleTree($roleAll);
    }

    public static function roleAdmin()
    {
        $roleAll = self::where('sys',0)->where('status',1)->field('id,parent,path,role_name')->order('pid ASC,id ASC')->select();
        return self::tidySelectTree($roleAll);
    }

    /**
     * 获取管理员select
     * @param int $pid
     * @param int $sys [sys]0=部门1=职位2=部门+职位
     * @param array $data
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getSelect($pid = 0,$sys = 0, $data = []) {
        $query = self::where('status',1);
        if($sys == 0) {
            $query->where('sys', 0);
        }
        if($pid) {
            $branch = self::where('id', $pid)->where('sys', 0)->find();
            if(!empty($branch)) {
                $query->whereNotIn('id',$branch['path'])->whereOr('id',$pid);
            }
        } else if(!empty($data) && $data['sys'] == 0) {
            $query->whereNotIn('id',$data['path']);
        }

        $query->order('pid asc,type asc,id asc');
        $data = $query->column('parent,role_name,sys','id');
        $list = [];
        foreach($data as $k=>$v) {
            if($v['sys'] == $sys || $sys == 2) {
                $name = self::getNmaes($v['parent'], $data, $v['role_name']);
                $list[$k] = $name;
            }
        }
        return $list;
    }

    /*
     * 子菜单列表
     */
    public static function setPath() {
        $result = self::order('id ASC')->select()->toArray();
        if(is_array($result)) {
            foreach($result as $r) {
                $pid = self::getPid($r['id'],$r['parent'],$result);
                $type = self::getType(1,$r['parent'],$result);
                $path = self::getPath($r['id'],$result);
                $child = is_numeric($path) ? 0 : 1;
                self::where('id',$r['id'])->update(['pid'=>$pid,'type'=>$type,'child'=>$child,'path'=>$path]);
            }
        }
        return true;
    }

    public static function rolesByAuth($roleid)
    {
        if(!$roleid) return [];
        $roles = self::where('id', $roleid)->where('status','1')->column('roles','id');
        $roles = array_unique(explode(',',implode(',',$roles)));
        $_auth = SystemMenus::all(function($query) use($roles){
            $query->where('id','IN',$roles)
                ->where('visable', 1)
                ->field('id,controller,action');
        });
        return self::tidyAuth($_auth?:[]);
    }

    public static function getAllAuth()
    {
        static $auth = null;
        $auth === null && ($auth = self::tidyAuth(SystemMenus::all(function($query){
            $query->where('visable', 1)->field('id,controller,action');
        })?:[]));
        return $auth;
    }

    protected static function tidyAuth($_auth)
    {
        $auth = [];
        foreach ($_auth as $k=>$val){
            $auth[$val['id']] =  SystemMenus::getAuthName($val['action'],$val['controller']);
        }
        return $auth;
    }

    /**
     * 获取管理员下拉列表
     * @param $roleList
     * @param int $pid
     * @param array $navList
     * @return array
     */
    protected static function tidySelectTree($roleList)
    {
        $navList = [];

        foreach ($roleList as $k => $role) {
            $role = $role->getData();
            $role['sales'] = SystemAdmin::where('roleid','IN', $role['path'])->where('is_del', 0)->column('id,real_name','id');
            if($role['sales']) $navList[] = $role;
        }
        return $navList;
    }

    /**
     * @param $roleList
     * @param int $pid
     * @param array $navList
     * @return array
     */
    protected static function tidyRoleTree($roleList, $parent = 0, $navList = [])
    {
        foreach ($roleList as $k => $role) {
            $role = $role->getData();
            if ($role['parent'] == $parent) {
                unset($roleList[$k]);
                $role['sale'] = SystemAdmin::where('roleid','IN', $role['path'])->where('is_del', 0)->count('id');
                $navList[] = $role;
                if(!$role['sys']) $navList = self::tidyRoleTree($roleList, $role['id'],$navList);
            }
        }
        return $navList;
    }

    /*
     * 递归获取名称
     */
    protected static function getNmaes($pid, $data, $name) {
        foreach($data as $k=>$v) {
            if($k == $pid) {
                $name = $v['role_name']. '﹏' .$name;
                if($v['parent']) {
                    $name = self::getNmaes($v['parent'], $data, $name);
                }
            }
        }
        return $name;
    }

    /*
     * 获取path
     */
    protected static function getPath($bid, $binfo) {
        $path = $bid;
        if(is_array($binfo)) {
            foreach($binfo as $bdata) {
                if($bdata['parent'] && $bdata['id'] != $bid && $bdata['parent']== $bid) {
                    $path .= ','. self::getPath($bdata['id'],$binfo);
                }
            }
        }
        return $path;
    }
    /*
     * 获取type层级
     */
    protected static function getType($type, $pid, $binfo) {
        $type2 = $type;
        if($pid > 0 && is_array($binfo)) {
            foreach($binfo as $bdata) {
                if($bdata['id'] == $pid) {
                    $type2 += self::getType($type,$bdata['parent'],$binfo);
                }
            }
        }
        return $type2;
    }

    /*
     * 获取终极部门id
     */
    protected static function getPid($id, $pid, $binfo) {
        $ppid = $id;
        if($pid > 0 && is_array($binfo)) {
            foreach($binfo as $bdata) {
                if($bdata['id'] == $pid) {
                    $ppid = self::getPid($pid,$bdata['parent'],$binfo);
                }
            }
        }
        return $ppid;
    }
}
